home *** CD-ROM | disk | FTP | other *** search
- /*
- Library for ftpd clients.(libftp)
- Copyright by Oleg Orel
- All rights reserved.
-
- This library is desined for free, non-commercial software creation.
- It is changeable and can be improved. The author would greatly appreciate
- any advises, new components and patches of the existing programs.
- Commercial usage is also possible with participation of it's author.
-
-
-
- */
-
- char intro[]="\
- Ftptry - try transfer via FTP.\n\
- Copyright by Oleg Orel is Reserved.\n\
- \n\
- This program is writen using \"libftp\".The main orientation for this\n\
- program is FTPing via bad-working network. Many network links are\n\
- down-up switched and networks are broaken, so the problem of\n\
- transfering large files exists. The main method, used by this\n\
- software is repetition until successfull transfer. There are some\n\
- keys for setting repetition and timeout intervals, modes of transfer\n\
- (binary and ascii), types of transfer (get,put,directory). All options\n\
- will be described in usage, if the program is started without them.\n\
- \n\
- The libftp you may transfer from host lpuds.oea.ihep.su via ftp-anonymous.\n\
- All question are sent to author via e-mail (orel@oea.ihep.su)\n\
- ";
-
- #include <FtpLibrary.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <signal.h>
- #include <setjmp.h>
-
- char *gethost();
- char *date();
-
-
- char
- *machine ="localhost",
- *user="anonymous",
- *password,
- *file=NULL,
- *localfile=NULL,
- *progname="ftptry";
-
-
- #define log(x) fprintf(stderr,"Ftptry %s::%s\n",date(),x)
- #define DEBUG(x) (debug?log(x):0)
- #define USERNAME (getenv("USER")==NULL?getenv("LOGNAME"):getenv("USER"))
- STATUS my_abort();
- STATUS my_IO();
- jmp_buf stack;
- int counter=0;
- String tmp;
-
- enum __type__ {ascii=1,binary};
- enum __bool__ {false,true};
- enum __mode__ {get=1,put,dir,multiget};
- enum __logmode__ {lm_tty,lm_file,lm_mail};
-
- char *p;
- FTP *ftp=NULL;
- int type=ascii;
- int sleeptime=600;
- int debug=false;
- int mode=get;
- int timeout=180;
- int overwrite=false;
- int logmode=lm_tty;
- char *logfile=NULL;
- FILE *LIST=NULL;
- extern int errno;
-
- main(int a,char **b)
- {
- FILE *out,*in;
- int c;
- extern char *optarg;
- extern int optind, opterr;
- String PASSWORD;
-
- sprintf(password=PASSWORD,"%s@%s",
- USERNAME,
- gethost());
-
- progname=b[0];
-
- if ( a<2 ) usage();
-
- while((c=getopt(a,b,"GOIBDru:p:Pdbs:o:l:t:cm"))!=EOF)
- {
- switch(c)
- {
-
- case 'G':
- mode=multiget;
- break;
-
- case 'O':
-
- overwrite=true;
- break;
-
- case 'c':
-
- localfile="*STDOUT*";
- break;
-
- case 'I':
- fprintf(stderr,intro);
- exit(0);
-
- case 'r':
-
- mode=put;
- break;
-
- case 'd':
-
- mode=dir;
- file=".";
- break;
-
- case 't':
-
- timeout=atoi(optarg);
- break;
-
- case 'l':
-
- localfile=optarg;
- break;
-
- case 'D':
-
- debug=true;
- break;
-
- case 'u':
-
- user=optarg;
- break;
-
- case 'p':
-
- password=optarg;
- break;
-
- case 'P':
-
- password=getpass("Password:");
- break;
-
- case 'b':
-
- type=binary;
- break;
-
- case 's':
-
- sleeptime=atoi(optarg);
- break;
-
- case 'o':
-
- logmode=lm_file;
- logfile=optarg;
- break;
-
- case 'm':
-
- logmode=lm_mail;
- break;
-
- case 'B':
-
- logmode=lm_file;
- logfile=NULL;
- break;
-
- default:
-
- usage();
-
- }
-
-
- }
-
-
- if (optind+1!=a) usage();
-
- if ((p=strchr(b[optind],':'))!=NULL)
- {
- file=p+1;
- machine=b[optind];
- *p=0;
- }
- else
- {
- file=b[optind];
- machine="localhost";
- }
-
-
- switch(mode)
- {
-
- case get:
- case put:
-
- if (*file==0) file="README";
- if (localfile==NULL) localfile=((p=strrchr(file,'/'))==NULL)?file:p+1;
- break;
-
- case dir:
-
- if (*file==0) file=".";
- if (localfile==NULL) localfile="*STDOUT*";
- break;
-
- case multiget:
-
- if (*file==0) file="*";
- if (localfile==NULL) localfile=".";
- break;
- }
-
- switch(logmode)
- {
-
- case lm_file:
-
- if (fork()) quit("Suspending.....");
- close(0);close(1);close(2);
- if (logfile==NULL)
- {
- sprintf(tmp,"/tmp/ftptry-%s.XXXXXX",USERNAME);
- mktemp(tmp);
- }
- else
- strcpy(tmp,logfile);
-
- open(tmp,O_TRUNC|O_CREAT|O_WRONLY,0600);
- dup(0);
- dup(0);
- break;
-
- case lm_mail:
-
- if (fork()) quit("Suspending.....");
- close(0);close(1);close(2);
-
- sprintf(tmp,"mail %s",USERNAME);
- popen(tmp,"w");
- dup(0);dup(0);
- break;
- }
-
-
- log((sprintf(tmp,"machine is %s, remote file is %s, local file is %s",
- machine,file,localfile),tmp));
-
- loop();
-
- }
-
- loop()
- {
- int r;
-
- counter=setjmp(stack);
-
- sprintf(tmp,"Start transfer %d's time",counter);
- DEBUG(tmp);
-
- if (debug) FtplibDebug(FTP_noexit);
-
- if ((r=FtpLogin(&ftp,machine,user,password,NULL))<1)
- {
- loop2();
- }
-
- FtpSetErrorHandler(ftp,my_abort);
- FtpSetIOHandler(ftp,my_IO);
- signal(SIGSEGV,loop2);
- signal(SIGPIPE,loop2);
-
- if (type==binary)
- FtpBinary(ftp);
-
- switch (mode)
- {
-
- case get:
-
- FtpGetTimeout(ftp,file,localfile,timeout);
- break;
-
- case put:
-
- FtpPutTimeout(ftp,localfile,file,timeout);
- break;
-
- case dir:
-
- FtpRetrTimeout(ftp,"LIST %s",file,localfile,timeout);
- break;
-
- case multiget:
- domultiget();
- break;
-
- }
-
- FtpBye(ftp);
-
- DEBUG("Transfer completed");
- exit(0); /* Not erase, but loop calling from lopp2 too. */
- }
-
- loop2()
- {
- String tmp;
- int i;
-
- DEBUG("Start pause");
- for (i=3;i<64;i++) close(i);
- sprintf(tmp,"Sleeping %d secs",sleeptime);
- DEBUG(tmp);
- sleep(sleeptime);
- DEBUG("Try againg....");
- longjmp(stack,counter+1);
- }
-
- quit(char *s)
- {
- extern int errno;
- log(s);
- exit(errno);
- }
-
-
- my_IO(FTP *ftp, int n, char *s)
- {
- extern int errno;
- DEBUG(strerror(errno));
- loop2();
- }
-
- my_abort(FTP *ftp, int n, char *s)
- {
- log(s);
- if ( abs(n) == 550 ) exit(-1) /* No access or not found */;
- loop2();
- }
-
-
- domultiget()
- {
- String list,localname,tmp_name;
-
-
- sprintf(list,"/tmp/ftptry-%s-multiget.XXXXXX",USERNAME);
- mktemp(list);
-
- FtpRetrTimeout(ftp,"NLST %s",file,list,timeout);
-
- if ((LIST=fopen(list,"r"))==NULL) quit(strerror(errno));
-
- while ( fgets (tmp, sizeof tmp, LIST) != NULL )
- {
- tmp[strlen(tmp)-1]=0;
-
- strcpy(localname,localfile);
- strcat(localname,"/");
- strcat(localname,(p=strrchr(tmp,'/'))==NULL?tmp:p+1);
-
- DEBUG(localname);
-
- strcpy(tmp_name,localname);
- strcat(tmp_name,"...ftptry");
-
- if (access(localname,F_OK)==0 && !overwrite)
- continue;
-
- FtpGetTimeout(ftp,tmp,tmp_name,timeout);
-
- link(tmp_name,localname);
- unlink(tmp_name);
- }
-
- fclose(LIST);
- LIST=NULL;
- return true;
- }
-
- usage()
- {
- fprintf(stderr,"\
- Usage: %s [optins] [host:file]\n\
- (default host \"localhost\",\n\
- default file \"README\" or \".\" in directory mode)\n\
- \n\
- Valid options:\n\
- \n\
- -u user default anonymous\n\
- -p password default %s\n\
- -P inquire password from your terminal\n\
- -l local_file use only if remote and local file differ\n\
- -c direct output to stdout(like cat)\n\
- -r reverse mode, i.e. send file to remote host\n\
- -d directory mode, remote file is patern or \"ls\" options\n\
- default output is stdout.\n\
- -G multiget mode, file is patern for \"ls\" command\n\
- -O Overwrite existing file(s). Use with -G to transfer all files\n\
- again at next try.\n\
- -b binary transfer mode\n\
- -s seconds Retry interval, default 10 minutes\n\
- -t seconds Timeout, default 3 minutes\n\
- -D Turn on debugging mode\n\
- -B Run in background and direct output to\n\
- /tmp/ftptry-%s.XXXXXX\n\
- -o file Run in background and direct output\n\
- to file\n\
- -m Send output to orel via e-mail\n\
- -I Print short introduction\n\
- \n\
- Example:\n\
- %s -Dbs 300 garbo.uwasa.fi:ls-lR.Z\n\
- Retrive file ls-lR.Z from garbo.uwasa.fi in binary mode\n\
- trying to reestablish connection every 5 minutes\n\
- on failure. Print debugging information.\n\
- ",progname,password,USERNAME,USERNAME,progname);
- exit(-1);
- }
-
- char *gethost()
- {
- static String tmp;
- String tmp2;
-
- gethostname(tmp2,sizeof tmp2);
-
- strcpy(tmp,gethostbyname(tmp2)->h_name);
- return tmp;
- }
-
-
- char *date()
- {
- static String s;
- time_t t=time((time_t *)0);
-
- strcpy(s,ctime(&t));
- s[strlen(s)-1]=0;
- return s;
- }
-
-